/****************************************************************************
* Copyright (c) 2008, j. montgomery, ATGi                                   *
* All rights reserved.                                                      *
*                                                                           *
* Redistribution and use in source and binary forms, with or without        *
* modification, are permitted provided that the following conditions        *
* are met:                                                                  *
*                                                                           *
* - Redistributions of source code must retain the above copyright          *
*   notice, this list of conditions and the following disclaimer.           *
*                                                                           *
* - Redistributions in binary form must reproduce the above                 *
*   copyright notice, this list of conditions and the following             *
*   disclaimer in the documentation and/or other materials provided         *
*   with the distribution.                                                  *
*                                                                           *
* - Neither the name of ATGi nor the names of its contributors may          *
*   be used to endorse or promote products derived from this software       *
*   without specific prior written permission.                              *
*                                                                           *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         *
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS         *
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE            *
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,       *
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES                  *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR        *
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        *
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,       *
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)             *
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED       *
* OF THE POSSIBILITY OF SUCH DAMAGE.                                        *
*****************************************************************************
*/
using System;
using DnSmtp.Message.Encoding;

namespace DnSmtp.Message
{
	/// <summary>
	/// See comp.mail.mime FAQ - http://www.uni-giessen.de/faq/archiv/mail.mime-faq.part1-9/msg00000.html
	/// http://ak-guetlich.chemie.uni-mainz.de/nt/ext/mime-faq/part5/faq.html
	/// See MIME Overview - http://www.mindspring.com/~mgrand/mime.html
	/// </summary>
	public struct MimeType
	{
		#region Fields
		private readonly string _contentType;
		private readonly string _contentSubtype;
		private readonly Message.Encoding.IEncodingStrategy _preferedEncodingStrategy;
		private readonly  string _fileExtension;
		#endregion Fields

        // Define each mimetype and the appropriate encoding stragegy
		public static readonly MimeType ApplicationMsword = new MimeType("application", "msword", Base64EncodingStrategy.Instance, ".doc");
		public static readonly MimeType ApplicationMsexcel  = new MimeType("application", "vnd.ms-excel", Base64EncodingStrategy.Instance, ".xls");
		public static readonly MimeType ApplicationOctetStream = new MimeType("application", "octet-stream", Base64EncodingStrategy.Instance, ".dat");
		public static readonly MimeType ApplicationXZipCompressed = new MimeType("application", "x-zip-compressed", Base64EncodingStrategy.Instance, ".zip");
		public static readonly MimeType ImageGif = new MimeType("image", "gif", Base64EncodingStrategy.Instance, ".gif");
		public static readonly MimeType ImageJpg = new MimeType("image", "jpg", Base64EncodingStrategy.Instance, ".jpg");
		public static readonly MimeType ImageJpeg = new MimeType("image", "jpeg", Base64EncodingStrategy.Instance, ".jpeg");
		public static readonly MimeType MessageRfc822 = new MimeType("message", "rfc822", QuotedPrintableEncodingStrategy.Instance, ".txt");
		public static readonly MimeType MultipartMixed = new MimeType("multipart", "mixed");
		public static readonly MimeType MultipartAlternative = new MimeType("multipart", "alternative");
		public static readonly MimeType TextHtml = new MimeType("text", "html", QuotedPrintableEncodingStrategy.Instance, ".html");
		public static readonly MimeType TextRichtext = new MimeType("text", "richtext", QuotedPrintableEncodingStrategy.Instance, ".rtf");
		public static readonly MimeType TextPlain = new MimeType("text", "plain", QuotedPrintableEncodingStrategy.Instance, "txt");
		public static readonly MimeType TextXAol = new MimeType("text","x-aol", EightBitEncodingStrategy.Instance, ".txt");
		public static readonly MimeType TextXml = new MimeType("text", "xml", EightBitEncodingStrategy.Instance, ".xml");
		public static readonly MimeType VideoMpeg = new MimeType("video","mpeg", Base64EncodingStrategy.Instance, ".mpeg");

		#region Properties
		public string ContentType 
		{
			get { return _contentType; }
		}

		public string ContentSubtype 
		{
			get { return _contentSubtype; }
		}

		public Message.Encoding.IEncodingStrategy PreferedEncodingStrategy 
		{
			get { return _preferedEncodingStrategy; }
		}

		public string FileExtension 
		{
			get { return _fileExtension; }
		}
		#endregion Properties

		#region Constructors
		public MimeType(string contentType, string contentSubtype)
		{
			_contentType = contentType;
			_contentSubtype = contentSubtype;
			_preferedEncodingStrategy = Message.Encoding.Base64EncodingStrategy.Instance;
			_fileExtension = ".dat";
		}

		public MimeType(string contentType, string contentSubtype, Message.Encoding.IEncodingStrategy preferedEncodingStrategy, string fileExtension) : this(contentType, contentSubtype)
		{
			_preferedEncodingStrategy = preferedEncodingStrategy;
			_fileExtension = fileExtension;
		}
		#endregion Constructors

		public override string ToString()
		{
			return _contentType + "/" + _contentSubtype;
		}

		
		public static MimeType GetMimeTypeByExtension(string fileExtension) 
		{
			// TODO: Determine if there's a more elegant way to do this
			switch(fileExtension) 
			{
				case ".doc": 
				{
					return MimeType.ApplicationMsword;
				}
				case ".gif": 
				{
					return MimeType.ImageGif;
				}
				case ".html":
				case ".htm": 
				{
					return MimeType.TextHtml;
				}
				case ".jpeg": 
				{
					return MimeType.ImageJpeg;
				}
				case ".jpg": 
				{
					return MimeType.ImageJpg;
				}
				case ".mpg": 
				case ".mpeg": 
				{
					return MimeType.VideoMpeg;
				}
				case ".pdf": 
				{
					return MimeType.ApplicationOctetStream;
				}
				case ".txt": 
				{
					return MimeType.TextPlain;
				}
				case ".rtf": 
				{
					return MimeType.TextRichtext;
				}
				case ".xml": 
				{
					return MimeType.TextXml;
				}
				case ".xls": 
				{
					return MimeType.ApplicationMsexcel;
				}
				case ".zip": 
				{
					return MimeType.ApplicationXZipCompressed;
				}
				default: 
				{
					return MimeType.ApplicationOctetStream;
				}
			}
		}
	}
}

